classdef PRExportImportService < handle
    % PRExportImportService - PR表单数据导出导入服务
    % 遵循DO-178第4条规则：业务逻辑与GUI分离
    % 
    % 功能：
    % - 导出PR表单数据到JSON格式
    % - 导出PR表单数据到Markdown格式  
    % - 从JSON文件导入PR表单数据
    %
    % 作者：系统
    % 日期：2024-01-20
    % 版本：1.0
    
    methods (Static)
        
        function success = exportToJSON(prData, filePath)
            % 导出PR数据到JSON文件
            % 输入：
            %   prData - PR表单数据结构
            %   filePath - 输出文件路径
            % 输出：
            %   success - 导出是否成功
            
            try
                % 数据验证
                if isempty(prData)
                    error('PR数据不能为空');
                end
                
                if isempty(filePath)
                    error('文件路径不能为空');
                end
                
                % 确保输出目录存在
                [outputDir, ~, ~] = fileparts(filePath);
                if ~isempty(outputDir) && ~exist(outputDir, 'dir')
                    mkdir(outputDir);
                end
                
                % 转换数据格式以支持JSON序列化
                jsonData = PRExportImportService.prepareDataForJSON(prData);
                
                % 写入JSON文件
                jsonStr = jsonencode(jsonData, 'PrettyPrint', true);
                fid = fopen(filePath, 'w', 'n', 'UTF-8');
                if fid == -1
                    error('无法创建文件：%s', filePath);
                end
                
                fprintf(fid, '%s', jsonStr);
                fclose(fid);
                
                success = true;
                
            catch ME
                success = false;
                error('导出JSON失败：%s', ME.message);
            end
        end
        
        function success = exportToMarkdown(prData, filePath)
            % 导出PR数据到Markdown文件
            % 输入：
            %   prData - PR表单数据结构
            %   filePath - 输出文件路径
            % 输出：
            %   success - 导出是否成功
            
            try
                % 数据验证
                if isempty(prData)
                    error('PR数据不能为空');
                end
                
                if isempty(filePath)
                    error('文件路径不能为空');
                end
                
                % 确保输出目录存在
                [outputDir, ~, ~] = fileparts(filePath);
                if ~isempty(outputDir) && ~exist(outputDir, 'dir')
                    mkdir(outputDir);
                end
                
                % 生成Markdown内容
                mdContent = PRExportImportService.generateMarkdownContent(prData);
                
                % 写入Markdown文件
                fid = fopen(filePath, 'w', 'n', 'UTF-8');
                if fid == -1
                    error('无法创建文件：%s', filePath);
                end
                
                fprintf(fid, '%s', mdContent);
                fclose(fid);
                
                success = true;
                
            catch ME
                success = false;
                error('导出Markdown失败：%s', ME.message);
            end
        end
        
        function [success, prData] = importFromJSON(filePath)
            % 从JSON文件导入PR数据
            % 输入：
            %   filePath - JSON文件路径
            % 输出：
            %   success - 导入是否成功
            %   prData - 导入的PR数据结构
            
            try
                % 文件验证
                if isempty(filePath)
                    error('文件路径不能为空');
                end
                
                if ~exist(filePath, 'file')
                    error('文件不存在：%s', filePath);
                end
                
                % 读取JSON文件
                fid = fopen(filePath, 'r', 'n', 'UTF-8');
                if fid == -1
                    error('无法打开文件：%s', filePath);
                end
                
                jsonStr = fread(fid, '*char')';
                fclose(fid);
                
                % 解析JSON
                jsonData = jsondecode(jsonStr);
                
                % 转换回PR数据格式
                prData = PRExportImportService.convertFromJSON(jsonData);
                
                success = true;
                
            catch ME
                success = false;
                prData = [];
                error('导入JSON失败：%s', ME.message);
            end
        end
        
    end
    
    methods (Static, Access = private)
        
        function jsonData = prepareDataForJSON(prData)
            % 准备数据以支持JSON序列化
            % 支持PR API v2.0的15个字段（11必填+4可选）
            jsonData = struct();
            
            % ========== 必填字段（11个）==========
            % 基础信息（5个）
            if isfield(prData, 'project')
                jsonData.project = prData.project;
            end
            if isfield(prData, 'issueNumber')
                jsonData.issueNumber = prData.issueNumber;
            end
            if isfield(prData, 'reporter')
                jsonData.reporter = prData.reporter;
            end
            if isfield(prData, 'source')
                jsonData.source = prData.source;
            end
            if isfield(prData, 'initialSeverity')
                jsonData.initialSeverity = prData.initialSeverity;
            end
            
            % 问题描述和分析（4个）
            if isfield(prData, 'problemDescription')
                jsonData.problemDescription = PRExportImportService.cellArrayToString(prData.problemDescription);
            end
            if isfield(prData, 'problemMechanism')
                jsonData.problemMechanism = PRExportImportService.cellArrayToString(prData.problemMechanism);
            end
            if isfield(prData, 'relatedRequirements')
                jsonData.relatedRequirements = prData.relatedRequirements;
            end
            if isfield(prData, 'impactAnalysis')
                jsonData.impactAnalysis = PRExportImportService.cellArrayToString(prData.impactAnalysis);
            end
            
            % 分配和审批（2个）
            if isfield(prData, 'assignee')
                jsonData.assignee = prData.assignee;
            end
            if isfield(prData, 'approver')
                jsonData.approver = prData.approver;
            end
            
            % ========== 可选字段（4个）==========
            if isfield(prData, 'baseline')
                jsonData.baseline = prData.baseline;
            end
            if isfield(prData, 'verificationStatus')
                jsonData.verificationStatus = PRExportImportService.cellArrayToString(prData.verificationStatus);
            end
            if isfield(prData, 'confirmedSeverity')
                jsonData.confirmedSeverity = prData.confirmedSeverity;
            end
            if isfield(prData, 'disposalPlan')
                jsonData.disposalPlan = PRExportImportService.cellArrayToString(prData.disposalPlan);
            end
            
            % ========== 向后兼容旧版本字段 ==========
            % 如果存在旧版本字段，也保留
            if isfield(prData, 'changeDescription')
                jsonData.changeDescription = PRExportImportService.cellArrayToString(prData.changeDescription);
            end
            if isfield(prData, 'analysis')
                jsonData.analysis = PRExportImportService.cellArrayToString(prData.analysis);
            end
            
            % 添加导出时间戳
            jsonData.exportTime = char(datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss'));
            jsonData.exportVersion = '2.0';  % 更新版本号
        end
        
        function mdContent = generateMarkdownContent(prData)
            % 生成Markdown内容 - 支持PR API v2.0
            mdContent = sprintf('# PR表单数据 (API v2.0)\n\n');
            mdContent = [mdContent sprintf('**生成时间：** %s\n\n', datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss'))];
            
            % 基础信息表格
            mdContent = [mdContent sprintf('## 基础信息\n\n')];
            mdContent = [mdContent sprintf('| 字段 | 值 |\n')];
            mdContent = [mdContent sprintf('|------|-----|\n')];
            if isfield(prData, 'project')
                mdContent = [mdContent sprintf('| 项目名称 | %s |\n', prData.project)];
            end
            if isfield(prData, 'issueNumber')
                mdContent = [mdContent sprintf('| 问题编号 | %s |\n', prData.issueNumber)];
            end
            if isfield(prData, 'reporter')
                mdContent = [mdContent sprintf('| 提报人 | %s |\n', prData.reporter)];
            end
            if isfield(prData, 'source')
                mdContent = [mdContent sprintf('| 问题来源 | %s |\n', prData.source)];
            end
            if isfield(prData, 'initialSeverity')
                mdContent = [mdContent sprintf('| 初定严重度 | %s |\n', prData.initialSeverity)];
            end
            if isfield(prData, 'assignee')
                mdContent = [mdContent sprintf('| 分配人员 | %s |\n', prData.assignee)];
            end
            if isfield(prData, 'approver')
                mdContent = [mdContent sprintf('| 审批人 | %s |\n', prData.approver)];
            end
            if isfield(prData, 'baseline')
                mdContent = [mdContent sprintf('| 基线信息 | %s |\n', prData.baseline)];
            end
            if isfield(prData, 'confirmedSeverity')
                mdContent = [mdContent sprintf('| 确定严重度 | %s |\n', prData.confirmedSeverity)];
            end
            mdContent = [mdContent sprintf('\n')];
            
            % 问题描述
            if isfield(prData, 'problemDescription')
                mdContent = [mdContent sprintf('## 问题描述\n\n')];
                problemDesc = PRExportImportService.cellArrayToString(prData.problemDescription);
                mdContent = [mdContent sprintf('%s\n\n', problemDesc)];
            end
            
            % 问题机理
            if isfield(prData, 'problemMechanism')
                mdContent = [mdContent sprintf('## 问题机理和复现情况\n\n')];
                mechanism = PRExportImportService.cellArrayToString(prData.problemMechanism);
                mdContent = [mdContent sprintf('%s\n\n', mechanism)];
            end
            
            % 关联需求
            if isfield(prData, 'relatedRequirements')
                mdContent = [mdContent sprintf('## 关联需求\n\n')];
                mdContent = [mdContent sprintf('%s\n\n', prData.relatedRequirements)];
            end
            
            % 影响性分析
            if isfield(prData, 'impactAnalysis')
                mdContent = [mdContent sprintf('## 影响性分析\n\n')];
                impact = PRExportImportService.cellArrayToString(prData.impactAnalysis);
                mdContent = [mdContent sprintf('%s\n\n', impact)];
            end
            
            % 验证状态
            if isfield(prData, 'verificationStatus')
                mdContent = [mdContent sprintf('## 验证状态\n\n')];
                verification = PRExportImportService.cellArrayToString(prData.verificationStatus);
                mdContent = [mdContent sprintf('%s\n\n', verification)];
            end
            
            % 处置计划
            if isfield(prData, 'disposalPlan')
                mdContent = [mdContent sprintf('## 处置计划\n\n')];
                disposal = PRExportImportService.cellArrayToString(prData.disposalPlan);
                mdContent = [mdContent sprintf('%s\n\n', disposal)];
            end
        end
        
        function prData = convertFromJSON(jsonData)
            % 从JSON数据转换回PR数据格式 - 支持PR API v2.0
            prData = struct();
            
            % ========== 必填字段（11个）==========
            % 基础信息（5个）
            if isfield(jsonData, 'project')
                prData.project = jsonData.project;
            end
            if isfield(jsonData, 'issueNumber')
                prData.issueNumber = jsonData.issueNumber;
            end
            if isfield(jsonData, 'reporter')
                prData.reporter = jsonData.reporter;
            end
            if isfield(jsonData, 'source')
                prData.source = jsonData.source;
            end
            if isfield(jsonData, 'initialSeverity')
                prData.initialSeverity = jsonData.initialSeverity;
            end
            
            % 问题描述和分析（4个）
            if isfield(jsonData, 'problemDescription')
                prData.problemDescription = PRExportImportService.stringToCellArray(jsonData.problemDescription);
            end
            if isfield(jsonData, 'problemMechanism')
                prData.problemMechanism = PRExportImportService.stringToCellArray(jsonData.problemMechanism);
            end
            if isfield(jsonData, 'relatedRequirements')
                prData.relatedRequirements = jsonData.relatedRequirements;
            end
            if isfield(jsonData, 'impactAnalysis')
                prData.impactAnalysis = PRExportImportService.stringToCellArray(jsonData.impactAnalysis);
            end
            
            % 分配和审批（2个）
            if isfield(jsonData, 'assignee')
                prData.assignee = jsonData.assignee;
            end
            if isfield(jsonData, 'approver')
                prData.approver = jsonData.approver;
            end
            
            % ========== 可选字段（4个）==========
            if isfield(jsonData, 'baseline')
                prData.baseline = jsonData.baseline;
            end
            if isfield(jsonData, 'verificationStatus')
                prData.verificationStatus = PRExportImportService.stringToCellArray(jsonData.verificationStatus);
            end
            if isfield(jsonData, 'confirmedSeverity')
                prData.confirmedSeverity = jsonData.confirmedSeverity;
            end
            if isfield(jsonData, 'disposalPlan')
                prData.disposalPlan = PRExportImportService.stringToCellArray(jsonData.disposalPlan);
            end
            
            % ========== 向后兼容旧版本字段 ==========
            if isfield(jsonData, 'changeDescription')
                prData.changeDescription = PRExportImportService.stringToCellArray(jsonData.changeDescription);
            end
            if isfield(jsonData, 'analysis')
                prData.analysis = PRExportImportService.stringToCellArray(jsonData.analysis);
            end
        end
        
        function str = cellArrayToString(cellArray)
            % 将cell数组转换为字符串
            if iscell(cellArray)
                str = strjoin(cellArray, '\n');
            else
                str = string(cellArray);
            end
        end
        
        function cellArray = stringToCellArray(str)
            % 将字符串转换为cell数组
            if ischar(str) || isstring(str)
                cellArray = strsplit(str, '\n');
            else
                cellArray = {str};
            end
        end
        
    end
end
